package com.xframe.xdal.core.model.sqlbuilder.proc;

import com.xframe.xdal.core.constant.DalConstants;
import com.xframe.xdal.core.model.mapping.IColumnMapping;
import com.xframe.xdal.core.model.sqlbuilder.BaseSqlBuilder;
import com.xframe.xdal.core.model.sqlbuilder.BuilderContext;
import com.xframe.xdal.core.model.sqlbuilder.DbExpression;
import com.xframe.xdal.core.model.sqlbuilder.SqlExpression;
import com.xframe.xdal.core.util.XReflect;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * 功能描述: manyinsert
 *
 * @version 1.0
 * @author：xufeng
 * @date: 2022/10/9 17:45
 **/
@Slf4j
public class OracleManyInsertBuilder extends BaseSqlBuilder {

    /**
     * manyinsert sql语句模板
     * @return
     */
    public String getSQL() {
        return  "INSERT ALL %s" + " SELECT * FROM DUAL";
    }

    public static final String INSERTSQL = "INTO %s(%s) VALUES(%s)";


    @Override
    public SqlExpression build(BuilderContext context) {
        List<Object> paramList = new ArrayList<>();
        List<String> fieldNameList = new ArrayList<>();
        String SQL = buildHelp(context,fieldNameList);
        //log.info(SQL);

        StringBuilder sqlBuilder = new StringBuilder();
        sqlBuilder.append("INSERT ALL ");
        context.getData().getCollection().forEach(objItem -> createStrBuilder(objItem,SQL, sqlBuilder, paramList,fieldNameList));
        sqlBuilder.append(" SELECT * FROM DUAL");

        return new SqlExpression(sqlBuilder.toString(), paramList,context.getDataSourceTypeEnums());

    }

    private void createStrBuilder(Object objItem,String SQL,StringBuilder
            sqlBuilder,List<Object> paramList,List<String> fieldNameList){
        sqlBuilder.append(SQL);
        for(String fieldName : fieldNameList){
            paramList.add(XReflect.getFieldValue(objItem,fieldName));
        }

    }




    private String buildHelp(BuilderContext context,List<String> fieldNameList) {

        List<IColumnMapping> columnMappings = context.findNotDbGenerated();
        log.info("columnMappings = {}", columnMappings);
        StringBuilder colstrBuilder = new StringBuilder();
        StringBuilder valstrBuilder = new StringBuilder();

        for (int index = 0; index < columnMappings.size(); index++) {
            IColumnMapping columnMapping = columnMappings.get(index);

            colstrBuilder.append(context.getNameConvert().toName(columnMapping.getName()));
            if (columnMapping.getUseDbObjectFlag()) {
                String dbExp = DbExpression.getDbExpression().getExpression(columnMapping.getDbExpression(), context.getDataSourceTypeEnums());
                valstrBuilder.append(dbExp);
            } else {

                valstrBuilder.append(DalConstants.SQL_PLACE_HOlDER);
                fieldNameList.add(columnMapping.getFieldName());
            }
            if (index + 1 < columnMappings.size()) {
                colstrBuilder.append(DalConstants.SQL_SEPARATION);
                valstrBuilder.append(DalConstants.SQL_SEPARATION);
            }
        }
        return String.format(INSERTSQL, context.getNameConvert().toName(context.getTableInfo().getName()), colstrBuilder, valstrBuilder);

    }
}
